package okl.lab.namesFilter.tests.cases
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	
	import mx.collections.ArrayCollection;
	import mx.events.FlexEvent;
	
	import okl.lab.components.FilterAndSortList;
	import okl.lab.components.interfaces.IFilterAndSortList;
	import okl.lab.namesFilter.controller.events.UsersEvent;
	import okl.lab.namesFilter.model.vo.User;
	import okl.lab.namesFilter.tests.utils.TestDataGenerator;
	import okl.lab.namesFilter.view.FilterAndSortListView;
	import okl.lab.namesFilter.view.mediators.FilterAndSortMediator;
	
	import org.flexunit.asserts.assertEquals;
	import org.flexunit.asserts.assertNotNull;
	import org.flexunit.asserts.fail;
	import org.flexunit.async.Async;
	import org.fluint.uiImpersonation.UIImpersonator;

	public class FilterAndSortListMediationTest
	{		
		private var ui:IFilterAndSortList;
		private var mediator:FilterAndSortMediator;
		private var rndUsers:ArrayCollection;
		private var users:ArrayCollection;
		private var dispatcher:EventDispatcher;
		[Before(async, ui)]
		public function setUp():void
		{
			dispatcher=new EventDispatcher();
			rndUsers = new ArrayCollection(TestDataGenerator.generateUsers(100));
			
			users = new ArrayCollection([
				TestDataGenerator.createUser("britney", "spears", true),
				TestDataGenerator.createUser("Alex", "Kul"),
				TestDataGenerator.createUser("Freddy", "Crouger"),
				TestDataGenerator.createUser("Ali", ""),
				TestDataGenerator.createUser("", "Lector"),
				TestDataGenerator.createUser("Ali", "Kulin")
			]);
			//ui<->mediator
			ui = new FilterAndSortListView();
			mediator = new FilterAndSortMediator();
			mediator.eventDispatcher = dispatcher;
			mediator.view = ui;
			mediator.setViewComponent(ui);
			mediator.onRegister();
			
			Async.proceedOnEvent(this, ui, FlexEvent.CREATION_COMPLETE);
			UIImpersonator.addChild(ui as FilterAndSortListView);
		}
		
		
		
		[Test]
		public function testMediatorMapping():void
		{
			assertNotNull( this.mediator.view );
			assertNotNull( this.mediator.getViewComponent() );
		}
		
		[Test(async,ui)]
		public function testReceiveUserLoadedEvent():void
		{
			var event:UsersEvent = new UsersEvent(UsersEvent.UPDATED);
			event.users = rndUsers;
			
			Async.handleEvent(this, dispatcher, UsersEvent.UPDATED, handleUserLoadedEvent, 500, event, handleTimeout);
			//using fake dispatcher to access event bus (model should dispatch this event)
			dispatcher.dispatchEvent(event);
		}
		
		[Test(async,ui)] 
		public function testDataProviderUpdateAfterLoadedUsersEvent():void
		{
			var event:UsersEvent = new UsersEvent(UsersEvent.UPDATED);
			event.users = rndUsers;
			
			Async.handleEvent(this, ui, "dataChange", handleDataProviderChange, 500, event, handleTimeout);
			dispatcher.dispatchEvent(event);
		}
		

		[Test(async,ui)] 
		public function testFilteringUsingSearchTerm():void
		{
			ui.dataProvider=users;
			Async.handleEvent(this, ui, "change", testFilteringUsingSearchTermCallback, 500, null, handleTimeout);
			ui.searchTerm = "Ku";
			//TODO: add similar tests for
			/*
			ui.searchTerm = "NotExisting"
			assertEquals(ui.dataFiltered.length, 0);
			
			ui.searchTerm = "britney"
			assertEquals(ui.dataFiltered.length, 0);
			
			ui.searchTerm = "SPeArs"
			assertEquals(ui.dataFiltered.length, 1);
			*/
		
		}
		
		[Test(async,ui)] 
		public function testFilteringUsingSortFields():void
		{
			ui.dataProvider=users;
			ui.searchTerm="Ku"
			Async.handleEvent(this, ui, "change", testFilteringUsingSearchTermCallback, 500, null, handleTimeout);
			ui.dataSortFields = []
		}

		
		//{region ASYNC_CALLBACKS
		protected function handleTimeout( event:Object ):void
		{
			fail("Event Timeout");
		}
		
		protected function handleUserLoadedEvent(event:UsersEvent, expected:Object):void
		{
			assertEquals(event.users, expected.users);
		}
		protected function handleDataProviderChange(event:Event, expected:Object):void
		{
			assertEquals(ui.dataProvider, expected.users);
		}
		
		protected function testFilteringUsingSearchTermCallback(event:Event, expected:Object=null):void
		{
			//Ku
			assertNotNull(ui.dataFiltered);
			assertEquals(2, ui.dataFiltered.length);
			assertEquals("Kulin", ui.dataFiltered.getItemAt(1).lastName);
			assertEquals("Ali", ui.dataFiltered.getItemAt(1).firstName);
		}
		//}endregion
		
		[After(async,ui)]
		public function tearDown():void
		{			
			ui = null;
			mediator.onRemove();
			mediator.setViewComponent(null);
			mediator = null;
			rndUsers=null;
		
		}
		
	}
}